import sys
import os
import re
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QPushButton,
                             QHBoxLayout, QVBoxLayout, QListWidget, QSlider,
                             QFileDialog, QSplitter, QScrollArea)
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtCore import Qt, QUrl, QTimer, QSize
from PyQt5.QtGui import QPixmap, QFont, QIcon, QColor


def resource_path(relative_path):
    """资源路径处理"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)


class LyricsParser:
    def __init__(self):
        self.lyrics = []
        self.timestamps = []
        self.metadata = {}  # 新增元数据存储

    def parse_lrc(self, file_path):
        """解析LRC歌词文件"""
        self.lyrics = []
        self.timestamps = []
        self.metadata = {}

        try:
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                for line in f:
                    line = line.strip()
                    if not line or line[0] != '[':  # 跳过非歌词行
                        continue

                    # 手动提取时间标签
                    time_end = line.find(']')
                    if time_end == -1:  # 确保存在右括号
                        continue

                    time_str = line[1:time_end]
                    content = line[time_end + 1:].strip()

                    # 手动解析时间 mm:ss.xxx
                    if ':' in time_str and '.' in time_str:
                        mm_ss, xxx = time_str.split('.', 1)
                        mm, ss = mm_ss.split(':', 1)

                        # 计算毫秒时间戳
                        timestamp = int(mm) * 60000 + int(ss) * 1000 + int(xxx.ljust(3, '0')[:3])

                        # 处理元数据或歌词
                        if ':' in content and not content.startswith('['):
                            tag, value = content.split(':', 1)
                            self.metadata[tag.strip()] = value.strip()
                        else:
                            self.timestamps.append(timestamp)
                            self.lyrics.append(content)

        except Exception as e:
            print(f"解析错误: {str(e)}")


class AnimePlayer(QWidget):
    def __init__(self):
        super().__init__()
        self.player = QMediaPlayer()
        self.playlist = []
        self.current_index = 0
        self.lyrics_parser = LyricsParser()
        self.current_lyric_index = -1
        self.init_ui()
        self.init_player()

    def init_ui(self):
        """初始化界面布局"""
        self.setWindowIcon(QIcon(resource_path("resources/icon.ico")))
        self.setWindowTitle("月月音乐播放器")
        self.setGeometry(300, 300, 800, 600)
        self.setStyleSheet(self.load_stylesheet())

        # 主分割布局
        splitter = QSplitter(Qt.Horizontal)

        # 左侧区域（歌词+封面）
        left_widget = QWidget()
        left_layout = QVBoxLayout(left_widget)

        # 封面区域
        self.cover_label = QLabel()
        self.cover_label.setAlignment(Qt.AlignCenter)
        self.cover_label.setPixmap(QPixmap(resource_path("resources/cover.png")))
        left_layout.addWidget(self.cover_label)

        # 歌词显示区域
        self.lyrics_list = QListWidget()
        self.lyrics_list.setStyleSheet(self.lyrics_style())
        self.lyrics_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.lyrics_list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        left_layout.addWidget(self.lyrics_list)

        # 右侧区域（播放列表+控制）
        right_widget = QWidget()
        right_layout = QVBoxLayout(right_widget)

        # 进度条
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setStyleSheet(self.slider_style())

        # 播放列表
        self.list_widget = QListWidget()
        self.list_widget.setStyleSheet(self.list_style())
        self.list_widget.itemDoubleClicked.connect(self.play_selected)

        # 控制按钮
        control_layout = QHBoxLayout()
        self.btn_prev = self.create_icon_button("prev")
        self.btn_play = self.create_icon_button("play")
        self.btn_next = self.create_icon_button("next")
        self.btn_open = self.create_icon_button("open")
        control_layout.addWidget(self.btn_prev)
        control_layout.addWidget(self.btn_play)
        control_layout.addWidget(self.btn_next)
        control_layout.addWidget(self.btn_open)

        # 组装右侧布局
        right_layout.addWidget(self.slider)
        right_layout.addLayout(control_layout)
        right_layout.addWidget(self.list_widget)

        # 设置分割器
        splitter.addWidget(left_widget)
        splitter.addWidget(right_widget)
        splitter.setSizes([400, 400])

        main_layout = QHBoxLayout(self)
        main_layout.addWidget(splitter)

    def init_player(self):
        """初始化播放器组件"""
        self.player.setVolume(50)
        self.slider.sliderMoved.connect(self.set_position)
        self.player.durationChanged.connect(self.update_duration)
        self.player.positionChanged.connect(self.update_position)
        self.player.mediaStatusChanged.connect(self.handle_media_status)

        # 歌词更新定时器
        self.lyric_timer = QTimer()
        self.lyric_timer.timeout.connect(self.update_lyrics)

    def load_lyrics(self, music_path):
        """自动加载歌词文件"""
        lrc_path = os.path.splitext(music_path)[0] + ".lrc"
        print(lrc_path)
        if os.path.exists(lrc_path):
            self.lyrics_parser.parse_lrc(lrc_path)
            self.lyrics_list.clear()

            # 显示元数据
            if self.lyrics_parser.metadata:
                metadata_text = "\n".join([f"{k}: {v}" for k, v in self.lyrics_parser.metadata.items()])
                self.lyrics_list.addItem(metadata_text)
                self.lyrics_list.addItem("")  # 添加空行分隔

            self.lyrics_list.addItems(self.lyrics_parser.lyrics)
            self.current_lyric_index = -1
        else:
            self.lyrics_list.clear()
            self.lyrics_list.addItem("未找到歌词文件")

    def update_lyrics(self):
        """更新当前歌词显示"""
        if not self.lyrics_parser.timestamps:
            return

        position = self.player.position()
        lyrics = self.lyrics_parser
        index = None

        # 查找当前歌词索引
        for i, ts in enumerate(lyrics.timestamps):
            if position >= ts:
                index = i
            else:
                break

        if index is not None and index != self.current_lyric_index:
            self.current_lyric_index = index
            self.lyrics_list.setCurrentRow(index)
            self.lyrics_list.scrollToItem(
                self.lyrics_list.item(index),
                QListWidget.PositionAtCenter
            )
            # 更新歌词样式
            for i in range(self.lyrics_list.count()):
                item = self.lyrics_list.item(i)
                if i == index:
                    # 当前播放的歌词
                    item.setForeground(QColor(244, 124, 60))
                    font = item.font()
                    font.setBold(True)
                    font.setPointSize(14)
                    item.setFont(font)
                else:
                    # 非当前播放的歌词
                    item.setForeground(QColor(200, 200, 200))
                    font = item.font()
                    font.setBold(False)
                    font.setPointSize(12)
                    item.setFont(font)

    def handle_media_status(self, status):
        """处理播放结束"""
        if status == QMediaPlayer.EndOfMedia:
            self.play_next()

    def highlight_current_song(self):
        """高亮当前播放歌曲"""
        for i in range(self.list_widget.count()):
            item = self.list_widget.item(i)
            if i == self.current_index:
                item.setBackground(QColor(65, 105, 225))
                item.setForeground(QColor(255, 255, 255))
            else:
                item.setBackground(QColor(135, 206, 235, 30))
                item.setForeground(QColor(0, 0, 0))

    def play_next(self):
        """播放下一首"""
        if self.playlist:
            self.current_index = (self.current_index + 1) % len(self.playlist)
            self.play_current()

    def play_previous(self):
        """播放上一首"""
        if self.playlist:
            self.current_index = (self.current_index - 1) % len(self.playlist)
            self.play_current()

    def slider_style(self):
        """进度条样式"""
        return """
            QSlider::groove:horizontal {
                height: 8px;
                background: #87CEEB;
                border-radius: 4px;
            }
            QSlider::handle:horizontal {
                background: #4169E1;
                width: 16px;
                margin: -4px 0;
                border-radius: 8px;
            }
        """

    def list_style(self):
        """列表样式"""
        return """
            QListWidget {
                background: rgba(135,206,235, 0.3);
                font-size: 14px;
                color: #888888;
            }
            QListWidget::item {
                padding: 5px;
            }
        """

    def load_stylesheet(self):
        """主窗口样式"""
        return """
            QWidget {
                background: rgba(135,206,235, 0.1);
            }
            QLabel#cover_label {
                border: 2px solid #4169E1;
                border-radius: 15px;
            }
        """


    def on_button_click(self):
        """按钮点击事件处理:ml-citation{ref="5" data="citationList"}"""
        sender = self.sender()
        if sender.objectName() == "play":
            self.toggle_play()
        elif sender.objectName() == "prev":
            self.play_previous()
        elif sender.objectName() == "next":
            self.play_next()
        elif sender.objectName() == "open":
            self.load_music()


    def toggle_play(self):
        """播放/暂停切换:ml-citation{ref="5" data="citationList"}"""
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
            self.btn_play.setIcon(QIcon(resource_path("resources/icons/play.png")))
        else:
            self.player.play()
            self.btn_play.setIcon(QIcon(resource_path("resources/icons/pause.png")))

    def load_music(self):
        """加载音乐文件:ml-citation{ref="5" data="citationList"}"""
        folder = QFileDialog.getExistingDirectory(self, "选择音乐文件夹")
        if folder:
            self.playlist = [os.path.join(folder, f) for f in os.listdir(folder)
                             if f.endswith(('.mp3', '.wav', '.flac'))]
            self.list_widget.clear()
            self.list_widget.addItems([os.path.basename(f) for f in self.playlist])
            if self.playlist:
                self.play_music(0)
                self.play_current()


    def play_music(self, index):
        """播放指定索引的音乐:ml-citation{ref="5" data="citationList"}"""
        if 0 <= index < len(self.playlist):
            self.current_index = index
            media = QMediaContent(QUrl.fromLocalFile(self.playlist[index]))
            self.player.setMedia(media)
            self.player.play()
            self.btn_play.setIcon(QIcon(resource_path("resources/icons/pause.png")))


    def set_position(self, position):
        """设置播放进度:ml-citation{ref="5" data="citationList"}"""
        self.player.setPosition(position)


    def update_duration(self, duration):
        """更新进度条长度:ml-citation{ref="5" data="citationList"}"""
        self.slider.setRange(0, duration)


    def update_position(self, position):
        """更新当前播放位置:ml-citation{ref="5" data="citationList"}"""
        self.slider.setValue(position)


    def play_selected(self, item):
        """双击播放列表项:ml-citation{ref="5" data="citationList"}"""
        index = self.list_widget.row(item)
        self.play_music(index)
        self.play_current()


    def create_icon_button(self, btn_type):
        """创建图标按钮"""
        btn = QPushButton()
        btn.setObjectName(btn_type)
        btn.setFixedSize(64, 64)

        # 设置图标样式
        icon_path = f"resources/icons/{btn_type}.png"
        btn.setIcon(QIcon(resource_path(icon_path)))
        btn.setIconSize(QSize(48, 48))

        # 按钮样式表
        btn.setStyleSheet("""
                           QPushButton {
                               background: transparent;
                               border: none;
                           }
                           QPushButton:hover {
                               background: rgba(255,105,180, 0.2);
                               border-radius: 32px;
                           }
                       """)
        btn.clicked.connect(self.on_button_click)
        return btn

    def lyrics_style(self):
        """歌词区域样式"""
        return """
            QListWidget {
                background: rgba(65, 105, 225, 0.1);
                font-size: 12px;
                color: #888888;
                border: 2px solid #4169E1;
                border-radius: 10px;
            }
            QListWidget::item {
                padding: 8px;
                text-align: center;
                border-bottom: 1px solid rgba(65, 105, 225, 0.2);
            }
        """

    # 修改原有play_current方法
    def play_current(self):
        """播放当前选中歌曲"""
        if self.playlist:
            music_path = self.playlist[self.current_index]
            content = QMediaContent(QUrl.fromLocalFile(music_path))
            self.player.setMedia(content)
            self.player.play()
            self.btn_play.setIcon(QIcon(resource_path("resources/icons/pause.png")))
            self.list_widget.setCurrentRow(self.current_index)
            self.highlight_current_song()
            self.load_lyrics(music_path)  # 加载歌词
            self.lyric_timer.start(100)  # 启动歌词更新定时器

    # 新增音乐停止时处理
    def handle_media_status(self, status):
        """处理媒体状态变化"""
        if status == QMediaPlayer.EndOfMedia:
            self.play_next()
        elif status == QMediaPlayer.LoadedMedia:
            self.lyric_timer.start(100)
        elif status == QMediaPlayer.NoMedia:
            self.lyric_timer.stop()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    player = AnimePlayer()
    player.show()
    sys.exit(app.exec_())
